package com.zszedu.web.controller;

import com.zszedu.pay.Pkipair;
import com.zszedu.pojo.Recharge;
import com.zszedu.pojo.User;
import com.zszedu.service.AccountService;
import com.zszedu.service.RechargeService;
import com.zszedu.service.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Controller
public class PayController {

    @DubboReference
    private UserService userService;

    @DubboReference
    private RechargeService rechargeService;

    @DubboReference
    private AccountService accountService;

    //用户支付后的处理结果，等待扣款(成功/失败)
    @GetMapping("pay/result")
    @ResponseBody
    public String payResult(HttpServletRequest request) {
        String merchantAcctId = request.getParameter("merchantAcctId");
        String version = request.getParameter("version");
        String language = request.getParameter("language");
        String signType = request.getParameter("signType");
        String payType = request.getParameter("payType");
        String bankId = request.getParameter("bankId");
        String orderId = request.getParameter("orderId");
        String orderTime = request.getParameter("orderTime");
        String dealId = request.getParameter("dealId");
        String orderAmount = request.getParameter("orderAmount");
        String bindCard = "";
        if (request.getParameter("bindCard") != null) {
            bindCard = request.getParameter("bindCard");
        }
        String bindMobile = "";
        if (request.getParameter("bindMobile") != null) {
            bindMobile = request.getParameter("bindMobile");
        }
        String bankDealId = request.getParameter("bankDealId");
        String dealTime = request.getParameter("dealTime");
        String payAmount = request.getParameter("payAmount");
        String fee = request.getParameter("fee");
        String ext1 = request.getParameter("ext1"); // 用户id
        String ext2 = request.getParameter("ext2");
        String payResult = request.getParameter("payResult");
        String aggregatePay = request.getParameter("aggregatePay");
        String errCode = request.getParameter("errCode");
        String signMsg = request.getParameter("signMsg");
        String merchantSignMsgVal = "";
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "merchantAcctId", merchantAcctId);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "version", version);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "language", language);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "signType", signType);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "payType", payType);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankId", bankId);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderId", orderId);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderTime", orderTime);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderAmount", orderAmount);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "bindCard", bindCard);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "bindMobile", bindMobile);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealId", dealId);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankDealId", bankDealId);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealTime", dealTime);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "payAmount", payAmount);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "fee", fee);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext1", ext1);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext2", ext2);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "payResult", payResult);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "aggregatePay", aggregatePay);
        merchantSignMsgVal = appendParam(merchantSignMsgVal, "errCode", errCode);
        System.out.println("merchantSignMsgVal=" + merchantSignMsgVal);
        Pkipair pki = new Pkipair();
        boolean flag = pki.enCodeByCer(merchantSignMsgVal, signMsg);

        // 支付成功
        if (Integer.parseInt(payResult) == 10) {
            rechargeService.changeStatus(orderId, 1, payType);
            Double money = Double.valueOf(payAmount) / 100; // 分 ==> 元
            accountService.editAddMoney((long) Integer.parseInt(ext1), money);
        }
        // 支付失败
        else {
            rechargeService.changeStatus(orderId, 2, payType);
        }


        // 签名验证成功
        /*if (flag) {
            // 支付成功
            if (Integer.parseInt(payResult) == 10) {
                rechargeService.changeStatus(orderId, 1, payType);
                Double money = Double.valueOf(payAmount) / 100; // 分 ==> 元
                accountService.updateMoney(Integer.parseInt(ext1), money);
            }
            // 支付失败
            else {
                rechargeService.changeStatus(orderId, 2, payType);
            }
        }
        //  签名验证失败
        else {
            return "<result>0</result>";
        }*/

        return "<result>1</result>";
    }



    //进入第三方充值页面，等待用户扫码/银行卡 支付
    @GetMapping("pay")
    public ModelAndView toPay(Long uid, Double money, HttpServletRequest request) {
        System.out.println("测试1");
        User user = userService.queryById(uid);

        //人民币网关账号，该账号为11位人民币网关商户编号+01,该参数必填。
        String merchantAcctId = "1001214035601";//
        //编码方式，1代表 UTF-8; 2 代表 GBK; 3代表 GB2312 默认为1,该参数必填。
        String inputCharset = "1";
        //接收支付结果的页面地址，该参数一般置为空即可。
        String pageUrl = "";
        //服务器接收支付结果的后台地址，该参数务必填写，不能为空。
        String bgUrl = "127.0.0.1/pay/result";
        //网关版本，固定值：v2.0,该参数必填。
        String version = "v2.0";
        //语言种类，1代表中文显示，2代表英文显示。默认为1,该参数必填。
        String language = "1";
        //签名类型,该值为4，代表PKI加密方式,该参数必填。
        String signType = "4";
        //支付人姓名,可以为空。
        String payerName = "";
        //支付人联系类型，1 代表电子邮件方式；2 代表手机联系方式。可以为空。
        String payerContactType = "2";
        //支付人联系方式，与payerContactType设置对应，payerContactType为1，则填写邮箱地址；payerContactType为2，则填写手机号码。可以为空。
        String payerContact = user.getPhone();
        //指定付款人，可以为空,3代表付款方在商户方的会员编号
        String payerIdType = "3";
        //付款人标识，可以为空
        String payerId = uid + "";
        //付款人IP，可以为空
        String payerIP = request.getRemoteAddr();
        //商户订单号，以下采用时间来定义订单号，商户可以根据自己订单号的定义规则来定义该值，不能为空。
        String orderId = "YLB" + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
        //订单金额，金额以“分”为单位，商户测试以1分测试即可，切勿以大金额测试。该参数必填。
        Double m = money * 100;
        String orderAmount = m.intValue() + "";
        //订单提交时间，格式：yyyyMMddHHmmss，如：20071117020101，不能为空。
        String orderTime = new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
        //快钱时间戳，格式：yyyyMMddHHmmss，如：20071117020101， 可以为空
        String orderTimestamp = new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
        //商品名称，可以为空。
        String productName = "";
        //商品数量，可以为空。
        String productNum = "";
        //商品代码，可以为空。
        String productId = "";
        //商品描述，可以为空。
        String productDesc = "";
        //扩展字段1，商户可以传递自己需要的参数，支付完快钱会原值返回，可以为空。
        String ext1 = payerId;
        //扩展自段2，商户可以传递自己需要的参数，支付完快钱会原值返回，可以为空。
        String ext2 = "";
        //支付方式，一般为00，代表所有的支付方式。如果是银行直连商户，该值为10-1或10-2，必填。
        String payType = "00";
        //银行代码，如果payType为00，该值可以为空；如果payType为10-1或10-2，该值必须填写，具体请参考银行列表。
        String bankId = "";
        //同一订单禁止重复提交标志，实物购物车填1，虚拟产品用0。1代表只能提交一次，0代表在支付不成功情况下可以再提交。可为空。
        String redoFlag = "0";
        //快钱合作伙伴的帐户号，即商户编号，可为空。
        String pid = "";

        System.out.println("测试2");

        // signMsg 签名字符串 不可空，生成加密签名串
        String signMsgVal = "";
        Map<String, String> params = new HashMap<>();

        signMsgVal = appendParam(signMsgVal, "inputCharset", inputCharset, params);
        signMsgVal = appendParam(signMsgVal, "pageUrl", pageUrl, params);
        signMsgVal = appendParam(signMsgVal, "bgUrl", bgUrl, params);
        signMsgVal = appendParam(signMsgVal, "version", version, params);
        signMsgVal = appendParam(signMsgVal, "language", language, params);
        signMsgVal = appendParam(signMsgVal, "signType", signType, params);
        signMsgVal = appendParam(signMsgVal, "merchantAcctId", merchantAcctId, params);
        signMsgVal = appendParam(signMsgVal, "payerName", payerName, params);
        signMsgVal = appendParam(signMsgVal, "payerContactType", payerContactType, params);
        signMsgVal = appendParam(signMsgVal, "payerContact", payerContact, params);
        signMsgVal = appendParam(signMsgVal, "payerIdType", payerIdType, params);
        signMsgVal = appendParam(signMsgVal, "payerId", payerId, params);
        signMsgVal = appendParam(signMsgVal, "payerIP", payerIP, params);
        signMsgVal = appendParam(signMsgVal, "orderId", orderId, params);
        signMsgVal = appendParam(signMsgVal, "orderAmount", orderAmount, params);
        signMsgVal = appendParam(signMsgVal, "orderTime", orderTime, params);
        signMsgVal = appendParam(signMsgVal, "orderTimestamp", orderTimestamp, params);
        signMsgVal = appendParam(signMsgVal, "productName", productName, params);
        signMsgVal = appendParam(signMsgVal, "productNum", productNum, params);
        signMsgVal = appendParam(signMsgVal, "productId", productId, params);
        signMsgVal = appendParam(signMsgVal, "productDesc", productDesc, params);
        signMsgVal = appendParam(signMsgVal, "ext1", ext1, params);
        signMsgVal = appendParam(signMsgVal, "ext2", ext2, params);
        signMsgVal = appendParam(signMsgVal, "payType", payType, params);
        signMsgVal = appendParam(signMsgVal, "bankId", bankId, params);
        signMsgVal = appendParam(signMsgVal, "redoFlag", redoFlag, params);
        signMsgVal = appendParam(signMsgVal, "pid", pid, params);

        System.out.println("测试3");

        System.out.println(signMsgVal);
        Pkipair pki = new Pkipair();

        // 生成签名
        String signMsg = pki.signMsg(signMsgVal);

        System.out.println(signMsg);

        params.put("signMsg", signMsg);

        ModelAndView mv = new ModelAndView();
        mv.setViewName("pay.html");
        mv.addAllObjects(params);

        System.out.println("测试4");
        // 添加充值记录

        Recharge recharge = new Recharge();
        recharge.setUid(uid);
        recharge.setRechargeStatus(0);
        recharge.setRechargeTime(new Date());
        recharge.setRechargeMoney(money);
        recharge.setRechargeNo(orderId);
        recharge.setRechargeDesc("盈利宝账户充值");
        rechargeService.insert(recharge);
        
        System.out.println("测试5");
        return mv;
    }


    public String appendParam(String returns, String paramId, String paramValue, Map<String, String> params) {
        if (returns != "") {
            if (paramValue != "") {
                returns += "&" + paramId + "=" + paramValue;
            }
        } else {
            if (paramValue != "") {
                returns = paramId + "=" + paramValue;
            }
        }

        params.put(paramId, paramValue);
        return returns;
    }

    public String appendParam(String returns, String paramId, String paramValue) {
        if (returns != "") {
            if (paramValue != "") {
                returns += "&" + paramId + "=" + paramValue;
            }
        } else {
            if (paramValue != "") {
                returns = paramId + "=" + paramValue;
            }
        }
        return returns;
    }
}
